#ifndef QUEUE_H_
#define QUEUE_H_

#include <stdlib.h>

template <class T, int buffer_size>
class Queue
{
  public:
    Queue()
    {
      read_p = 0;
      write_p = 0;
      count = 0;
    }
    
    ~Queue()
    {
      free(buffer);
    }
    
    int size(void)
    {
      return count;
    }

    bool empty(void) const
    {
      if (count > 0) {
        return false;
      } else {
        return true;
      }
    }

    bool full(void) const
    {
      if (count >= buffer_size - 1) {
        return true;
      } else {
        return false;
      }
    }

    int capacity(void) const
    {
      return buffer_size;
    }
    
    T& front(void)
    {
      return buffer[read_p];
    }
    
    const T& front(void) const
    {
      return buffer[read_p];
    }
    
    void clear(void)
    {
      count = 0;
      write_p = 0;
      read_p = 0;
    }
    
    void push(const T &value)
    {
      buffer[write_p] = value;
      count++;
      if (count >= buffer_size) {
        count--;
      }
      write_p++;
      write_p %= buffer_size;
    }
    
    void pop(void)
    {
      if (count == 0) {
        count++;
      }
      count--;
      read_p++;
      read_p %= buffer_size;
    }

  private:
    int read_p;
    int write_p;
    int count;
    T buffer[buffer_size];
};

#endif /* QUEUE_H_ */
